#pragma once

#include <iostream>
#include <sys/poll.h>
#include "Sock.hpp"

static const int default_fd = -1;

static const short default_event = 0;

static const int N = 4096;

typedef struct pollfd type_t;

class PollServer
{
public:
    PollServer(uint16_t serverPort)
        :_serverPort(serverPort)
        ,_event(nullptr)
    {}

    void Init()
    {
        _sock.Socket();
        _sock.Bind(_serverPort);
        _sock.Listen();

        _event = new type_t[N];
        for(int i = 0; i < N; ++i)
        {
            _event[i].fd = default_fd;
            _event[i].events = default_event;
            _event[i].revents = default_event;
        }        
    }

    void Start()
    {
        _event[0].fd = _sock.Fd();//listent的sock获取网络链接，为读事件
        _event[0].events = POLLIN;
        while(true)
        {
            int timeout = 1000;//Poll的timeout单位是毫秒
            int n = poll(_event,N,timeout);
            if(n == 0)//timeout
            {
                LogMessage(Debug,"timeout");
            }
            else if(N < 0)
            {
                LogMessage(Error,"poll fail,%s,%d",strerror(errno),errno);
            }
            else
            {
                std::cout << "有一个事件就绪" << std::endl;
                HandlerEvent();
            }
        }
    }

    void HandlerEvent()
    {
        for(int i = 0; i < N; ++i)
        {
            if(_event[i].fd == default_fd)
                continue;
            if((_event[i].fd != default_fd) && (_event[i].revents & POLLIN))//读事件就绪
            {
                if(_event[i].fd == _sock.Fd())//新连接到来
                {   
                    Accepter();
                }   
                else//普通读事件
                {
                    Reader(_event[i].fd,i);
                }
            }
            else if((_event[i].fd != default_fd) && (_event[i].revents & POLLOUT))//写事件就绪
            {
                //TODO
            }
            else//其他事件就绪
            {
                //TODO
            }

        }
    }

    void Accepter()
    {
        std::string clientIp;
        uint16_t clientPort;
        int sock = _sock.Accept(&clientIp,&clientPort);
        if(sock > 0)
            LogMessage(Debug,"%s-%d accept success",clientIp.c_str(),clientPort);
        
        for(int i = 0; i < N; ++i)//添加到关心里
        {
            if(_event[i].fd != default_fd) continue;
            _event[i].fd = sock;
            //_event[i].events = POLLIN | POLLOUT;
            _event[i].events = POLLIN;
            _event[i].revents = default_event;
            break;
        }
    }

    void Reader(int sock,int i)
    {
        char buffer[1024];
        int n = recv(sock,buffer,sizeof(buffer)-1,0);
        if(n == 0)
        {
            LogMessage(Debug,"client exit");
            Close(i);
        }
        else if(n < 0)
        {
            LogMessage(Error,"recv fail,%s,%d",strerror(errno),errno);
            Close(i);
        }
        else
        {
            buffer[n] = '\0';
            std::cout << "client send# " << buffer << std::endl;
            std::string message = "server send# ";
            message += buffer;
            send(sock,message.c_str(),message.size(),0);
        }
    }

    void Close(int i)
    {
        close(_event[i].fd);
        _event[i].fd = default_fd;
        _event[i].events = default_event;
        _event[i].revents = default_event;
    }

    ~PollServer()
    {
        _sock.Close();
        if(_event) delete []_event;
    }
private:
    Sock _sock;
    uint16_t _serverPort;
    type_t* _event;
};
